#ifndef TC_CIRCARRAY_CPP
#define TC_CIRCARRAY_CPP

/** \file CircArray.cpp
 * Definitions for the templated class CircArray.
 *
 * (C) Copyright by Semih Cemiloglu
 * All rights reserved, see COPYRIGHT file for details.
 *
 * $Id: CircArray.cpp 110 2006-06-19 03:38:33Z semihc $
 *
 *
 */

#ifndef TC_CIRCARRAY_HPP
# include "CircArray.hpp"
#endif
#include "DBC.hpp"

namespace TC {

  template <typename T>
  void CircArray<T>::push(const T val)
  {
    if(m_cnt==m_lmt) {
      if(m_idx==m_lmt)
        m_idx = 0; // wrap-around
      m_sum -= m_arr[m_idx];
      m_arr[m_idx] = val;
      m_sum += val;
      ++m_idx;
    }
    else {
      m_arr[m_idx] = val;
      m_sum += val;
      ++m_idx;
      ++m_cnt;
    }
    
  } // end push()


  template <typename T>
  T CircArray<T>::max() const
  {
    T tmp = 0;
    if(m_cnt > 0) {
      tmp = m_arr[0];
      for(unsigned i=1; i<m_cnt; ++i)
        if(m_arr[i] > tmp)
          tmp = m_arr[i];
    }
    
    return tmp;
  }


  template <typename T>
  T CircArray<T>::min() const
  {
    T tmp = 0;
    if(m_cnt > 0) {
      tmp = m_arr[0];
      for(unsigned i=1; i<m_cnt; ++i)
        if(m_arr[i] < tmp)
          tmp = m_arr[i];
    }
    
    return tmp;
  }


  template <typename T>
  T CircArray<T>::avg() const
  {
    T tmp = m_sum;
    if(m_cnt > 0) {
      tmp /= m_cnt;
    }
    
    return tmp;
  }


  template <typename T>
  T CircArray<T>::at(unsigned pos) const
  {
    TC_PRE_CONDITION(pos < m_lmt);
    TC_PRE_CONDITION(pos < m_cnt);

    if(m_cnt==m_lmt) {
      // Find the beginning of the circular array
      pos += m_idx;
      pos %= m_cnt;
    }

    return m_arr[pos];
  }


} // end namespace

#endif /* Include guard */
